package com.atguigu.boot;

import ch.qos.logback.classic.db.DBHelper;
import com.atguigu.boot.bean.Pet;
import com.atguigu.boot.bean.User;
import com.atguigu.boot.config.MyConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties;
import org.springframework.cache.interceptor.CacheAspectSupport;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;

/**
 * 主程序类；主配置类
 *
 * @SpringBootApplication：这是一个SpringBoot应用
 */
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.atguigu.boot")
//@SpringBootApplication
public class MainApplication {


    public static void main(String[] args) {
        // 1、返回我们IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        // 2、查看容器里面的组件
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }

        // 查看容器中一共有多少个组件
        int beanDefinitionCount = run.getBeanDefinitionCount();
        System.out.println(beanDefinitionCount);
        // 查看容器中是否有某种类型的组件
        String[] beanNamesForType = run.getBeanNamesForType(CacheAspectSupport.class);
        System.out.println("======" + beanNamesForType.length);

        // 3、从容器中获取组件（默认单实例）
        String[] beanNamesForType1 = run.getBeanNamesForType(WebMvcProperties.class);
        System.out.println("======" + beanNamesForType1.length);
        // 验证：单实例
        Pet tom01 = run.getBean("tom22", Pet.class);
        Pet tom02 = run.getBean("tom22", Pet.class);
        System.out.println("单实例：" + (tom01 == tom02));

        // 4、配置类也是组件，并且获取到的是被[Spring CGLIB]增强的代理对象
        MyConfig bean = run.getBean(MyConfig.class);
        System.out.println(bean);// com.atguigu.boot.config.MyConfig$$EnhancerBySpringCGLIB$$51f1e1ca@1654a892
        // 验证：是从容器中拿，还是调用普通的方法
        // 如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有。
        // 一句话：保持组件单实例
        User user = bean.user01();
        User user1 = bean.user01();
        System.out.println(user == user1);// true
        // 验证：是否同一只宠物
        User user01 = run.getBean("user01", User.class);
        Pet tom = run.getBean("tom", Pet.class);
        System.out.println("用户的宠物和容器中的宠物是否同一只：" + (user01.getPet() == tom));


        // 5、获取@Import导入的组件
        String[] beanNamesForType2 = run.getBeanNamesForType(User.class);
        System.out.println("======");
        for (String s : beanNamesForType2) {
            System.out.println(s);
        }
        DBHelper bean2 = run.getBean(DBHelper.class);
        System.out.println(bean2);

        // 验证：条件装配
        boolean tom00 = run.containsBean("tom");
        System.out.println("容器中Tom组件：" + tom00);
        boolean user11 = run.containsBean("user01");
        System.out.println("容器中user01组件：" + user11);
        boolean tom22 = run.containsBean("tom22");
        System.out.println("容器中tom22组件：" + tom22);


        boolean haha = run.containsBean("haha");
        boolean hehe = run.containsBean("hehe");
        System.out.println("haha：" + haha);
        System.out.println("hehe：" + hehe);

    }
}
